/*
 * SalaRemota.cpp
 *
 *  Created on: 28/07/2014
 *      Author: migue
 */

#include "SalaRemota.h"
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

SalaRemota::SalaRemota(int numSala, Tipos::LugarDeSala lugar, int idCliente, int idBroker) :
	SalaDePersonas(numSala, lugar, false),
	_idShm(consultarId()),
	_mcs(idCliente, idBroker, _idShm)
{

}

SalaRemota::~SalaRemota() {
}

int SalaRemota::consultarId() {
	int id;
	if (this->lugar() == Tipos::LUGAR_ENTRADA) {
		id = ID_SHM_SALA_ENT(this->numeroDeSala());
	}
	else {
		id = ID_SHM_SALA_ZOO(this->numeroDeSala());
	}
	return id;
}

bool SalaRemota::hayPersonas() {
	return (_mcs.leerCantPersonas() > 0);
}

void SalaRemota::reservarLugar(int idPersona) {
	// Metodo Original
//	SALA sala;
//
//	_lugares->leer(0, (void*) &sala, sizeof(sala));
//
//	bool lugarReservado = false;
//	int i = 0;
//
//	for (; i < CANTMAX && lugarReservado == false; ++i) {
//		if (sala.personas[i] == LUGAR_VACIO) {
//			lugarReservado = true;
//			sala.personas[i] = -idPersona; // valor negativo de id significa reserva de ese id
//			sala.reservas++;
//		}
//	}
//
//	_lugares->escribir(0, (void*) &sala, sizeof(sala));
//
//	if (lugarReservado == false) {
//		syslog(LOG_INFO,
//				"No se logro Reservar lugar en la Sala con Persona con id: %i",
//				idPersona);
//		perror("No se logro reservar lugar en la Sala");
//	}

	bool lugarReservado = false;
	int i = 0;
	int id;

	for (; i < CANTMAX && lugarReservado == false ; ++i) {
		_mcs.leerPersona(i, id);
		if (id == LUGAR_VACIO) {
			lugarReservado = true;
			_mcs.escribirPersona(i, - idPersona);
			_mcs.escribirCantReservas(_mcs.leerCantReservas() + 1);
		}
	}

	if (lugarReservado == false) {
		syslog(LOG_INFO,
				"No se logro Reservar lugar en la Sala con Persona con id: %i",
				idPersona);
		perror("No se logro reservar lugar en la Sala");
	}

}

void SalaRemota::colocarEnReserva(int idPersona) {
	//Metodo Original
//	SALA sala;
//
//	_lugares->leer(0, (void*) &sala, sizeof(sala));
//
//	bool colocado = false;
//
//	for (int i = 0; i < CANTMAX && colocado == false; ++i) {
//
//		if (sala.personas[i] == -idPersona) {
//			colocado = true;
//			sala.personas[i] = idPersona;
//			sala.cantPersonas++;
//		}
//	}
//
//	if (colocado == false) {
//		syslog(LOG_INFO, "No se pudo colocar Persona id: %i en reserva",
//				idPersona);
//		perror("No se pudo colocar Persona en Reserva");
//	} else {
//		_lugares->escribir(0, (void*) &sala, sizeof(sala));
//	}

	bool colocado = false;
	int i = 0;
	int id;

	for (;i < CANTMAX && colocado == false ; ++i) {
		_mcs.leerPersona(i, id);

		if (id == -idPersona) {
			colocado = true;
			_mcs.escribirPersona(i, idPersona);
			_mcs.escribirCantPersonas(_mcs.leerCantPersonas() + 1);
		}


	}


	if (colocado == false) {
		syslog(LOG_INFO, "No se pudo colocar Persona id: %i en reserva",
				idPersona);
		perror("No se pudo colocar Persona en Reserva");
	}

}

int SalaRemota::verProximaPersona() {
	// Metodo Original
//	int proxId;
//
//	SALA sala;
//
//	_lugares->leer(0, (void*) &sala, sizeof(sala));
//
//	bool hayProx = false;
//	int i = 0;
//
//	for (; i < CANTMAX && hayProx == false && sala.cantPersonas > 0; ++i) {
//		if (sala.personas[i] > 0) {
//			proxId = sala.personas[i];
//			hayProx = true;
//		}
//	}
//
//	if (hayProx == false) {
//		return 0;
//	} else {
//		return proxId;
//	}

	int proxId;

	bool hayProx = false;
	int i = 0, id;

	int cantPersonas = _mcs.leerCantPersonas();

	for (; i < CANTMAX && hayProx == false && cantPersonas > 0 ; ++i) {
		_mcs.leerPersona(i, id);
		if (id > 0) {
			proxId = id;
			hayProx = true;
		}

	}

	if (hayProx)
		return proxId;
	else
		return 0;

}

void SalaRemota::sacarPersona(int idPersona) {
	//Metodo Original

//	SALA sala;
//
//	_lugares->leer(0, (void*) &sala, sizeof(sala));
//
//	bool encontrado = false;
//	int i = 0;
//
//	for (; i < CANTMAX && encontrado == false && sala.cantPersonas > 0; ++i) {
//		if (sala.personas[i] == idPersona) {
//			encontrado = true;
//			sala.personas[i] = LUGAR_VACIO;
//
//			sala.cantPersonas--;
//			sala.reservas--;
//		}
//	}
//
//	if (encontrado == false) {
//		perror("No se encontro persona para sacar de la Sala");
//	} else {
//		_lugares->escribir(0, (void*) &sala, sizeof(sala));
//	}


	bool encontrado = false;

	int cantPersonas = _mcs.leerCantPersonas();
	int cantReservas = _mcs.leerCantReservas();

	int i = 0;
	int id;
	for (; i < CANTMAX && encontrado == false && cantPersonas > 0; ++i) {
		_mcs.leerPersona(i, id);

		if (id == idPersona) {
			encontrado = true;
			_mcs.escribirPersona(i, LUGAR_VACIO);

			_mcs.escribirCantPersonas(cantPersonas - 1);
			_mcs.escribirCantReservas(cantReservas - 1);
		}
	}

}

int SalaRemota::cantidadDePersonas() {
	return _mcs.leerCantPersonas();
}

bool SalaRemota::salaLlena() {
	return (_mcs.leerCantReservas() == CANTMAX );
}

Tipos::EstadoBUS SalaRemota::estadoBUS() {
	Tipos::EstadoBUS est;
	_mcs.leerEstadoBUS(est);
	return est;
}


void SalaRemota::BUSsubiendoPersonas() {
	Tipos::EstadoBUS est = Tipos::BUS_SUBIENDO_PERS;
	_mcs.escribirEstadoBus(est);
}

void SalaRemota::BUSDespierto() {
	Tipos::EstadoBUS est = Tipos::BUS_ACTIVO;
	_mcs.escribirEstadoBus(est);
}

void SalaRemota::BUSbajandoPersonas() {
	Tipos::EstadoBUS est = Tipos::BUS_BAJANDO_PERS;
	_mcs.escribirEstadoBus(est);
}

void SalaRemota::BUSDormido() {
	Tipos::EstadoBUS est = Tipos::BUS_PARADO;
	_mcs.escribirEstadoBus(est);
}


void SalaRemota::inicializar() {
	// Metodo Original
//	SALA sala;
//
//	sala.cantPersonas = 0;
//	sala.reservas = 0;
//	sala.estadoBUS = Tipos::BUS_ACTIVO;
//
//	for (int i = 0; i < CANTMAX; ++i)
//		sala.personas[i] = 0;
//
//	_lugares->escribir(0, (void*) &sala, sizeof(sala));

	_mcs.escribirCantPersonas(0);
	_mcs.escribirCantReservas(0);
	_mcs.escribirEstadoBus(Tipos::BUS_ACTIVO);

	for (int i = 0; i < CANTMAX ; ++i){
		_mcs.escribirPersona(i, LUGAR_VACIO);
	}
}

void SalaRemota::destruir() {

}
